#include "Col.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "AccessMem.h"

#include "Class.h"
#include "Exception.h"

//---- AccessMembers -----------------------------------------------------------

AccessMembers::AccessMembers()
{
}

AccessMembers::~AccessMembers()
{
}

void AccessMembers::ClassName(char*)
{
}

void AccessMembers::Member(char*, int, int, int, Class*, bool, bool)
{
}

void AccessMembers::ScanMembers(Object *o, int first, va_list ap, int n)
{
	int len, tag, size;
	char *name;
	Class *cl;
	u_long th= (u_long) o, offset;
	bool global= FALSE, lenglobal= FALSE;

	if (o && o->IsA())
		size= o->IsA()->Size();
	else
		size= 999999; // very large (good idea ???)

	for (int i= 0; i < n; i++) {
		if (i == 0)
			tag= first;
		else
			tag= va_arg(ap, int);
		if (tag == T_SIM)
			tag= 0;
		name= va_arg(ap, char*);
		cl= va_arg(ap, Class*);
		offset= va_arg(ap, u_long);
		
		if (offset >= th && offset < th+size) {
			offset-= th;
			global= FALSE;
		} else
			global= TRUE;

		if (tag & T_VEC) {
			len= (int)va_arg(ap, u_long);
			if (len >= th && len < th+size) {
				len-= (int)th;
				lenglobal= FALSE;
			} else
				lenglobal= TRUE;
		} else if (tag & T_ARR)
			len= va_arg(ap, int);
		else
			len= -1;

		Member(name, (int) offset, len, tag, cl, global, lenglobal);
	}
	va_end(ap);
}

//---- AccessObjPtrs -----------------------------------------------------------

AccessObjPtrs::AccessObjPtrs(Object *op)
{
	inObject= op;
}

void AccessObjPtrs::ForObject(Object *op)
{
	inObject= op;
}

void AccessObjPtrs::Member(char *name, int offset, int offsetOrLen, int type,
										Class *cl, bool global, bool lenglobal)
{
	if (cl && cl->TestFlag(eClassObject)) {
		if ((type & T_PTR2) && (type & (T_ARR | T_VEC))) {
			Object **ov;
			int l= 0;

			if (type & T_ARR)
				l= offsetOrLen;
			else if (type & T_VEC) {
				void *ll;
				if (lenglobal)
					ll= (void*) offsetOrLen;
				else
					ll= (void*) ((u_long) inObject + (u_long) offsetOrLen);
				
				TRY {
					l= *((int*)ll);
				} CATCH(ex) {
					l= -1;
				} ENDTRY;
			}

			if (global)
				ov= *(Object***) offset;
			else
				ov= *(Object***)((u_long) inObject + (u_long) offset);

			if (ov && l > 0)
				for (int i= 0; i < l; i++)
					if (ov[i])
						FoundPointer(ov[i], name, i, FALSE);

		} else if (type & T_PTR) {
			if (global)
				FoundPointer(*(Object**)((u_long) offset), name, -1, TRUE);
			else
				FoundPointer(*(Object**)((u_long) inObject + (u_long) offset), name, -1, FALSE);
		} else if (type == 0) {     // inline Object
			if (global)
				FoundPointer((Object*)((u_long) offset), name, -1, TRUE);
			else
				FoundPointer((Object*)((u_long) inObject + (u_long) offset), name, -1, FALSE);
		}
	}
}

void AccessObjPtrs::FoundPointer(Object*, char*, int, bool)
{
}
